package cn.exrick.controller;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import cn.exrick.common.exception.NeedLoginException;
import cn.exrick.common.exception.XmallException;
import cn.exrick.common.jedis.JedisClient;
import cn.exrick.pojo.TbCollection;
import cn.exrick.pojo.TbItemSkuGoodCat;
import cn.exrick.pojo.TbItemSkuGoodCatAttr;
import cn.exrick.pojo.TbPanel;
import cn.exrick.pojo.TbPanelContent;
import cn.exrick.pojo.TbPreferential;
import cn.exrick.pojo.TbPreferentialItem;
import cn.exrick.pojo.common.Result;
import cn.exrick.pojo.dto.ItemDto;
import cn.exrick.pojo.dto.SkuDto;
import cn.exrick.pojo.front.Member;
import cn.exrick.pojo.front.Product;
import cn.exrick.pojo.front.SearchItem;
import cn.exrick.service.CollectionService;
import cn.exrick.service.ContentService;
import cn.exrick.service.ItemService;
import cn.exrick.service.ItemSkuGoodCatAttrService;
import cn.exrick.service.ItemSkuGoodCatService;
import cn.exrick.service.LoginService;
import cn.exrick.service.PreferentialItemService;
import cn.exrick.service.PreferentialService;
import cn.exrick.service.SearchService;
import cn.exrick.utils.HttpUtil;
import cn.exrick.utils.ResultUtil;
import cn.exrick.utils.mybatis.Page;
import cn.exrick.utils.mybatis.PageParam;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;

@RestController
@Api(description = "商品页面展示")
public class GoodsController {

    private final static Logger log = LoggerFactory.getLogger(GoodsController.class);

    @Autowired
    private ContentService contentService;

    @Autowired
    private SearchService searchService;

    @Autowired
    private CollectionService collectionService;

    @Autowired
    private LoginService loginService;

    @Autowired
    private ItemSkuGoodCatAttrService itemSkuGoodCatAttrService;
    @Autowired
    private ItemSkuGoodCatService itemSkuGoodCatService;
    @Autowired
    private ItemService itemService;

    @Autowired
    private JedisClient jedisClient;

    @Value("${ES_CONNECT_IP}")
    private String ES_CONNECT_IP;

    @Value("${ES_NODE_CLIENT_HTTP_PORT}")
    private String ES_NODE_CLIENT_HTTP_PORT;

    @Autowired
    private PreferentialService preferentialService;

    @Autowired
    private PreferentialItemService preferentialItemService;

    @RequestMapping(value = "/goods/navList", method = RequestMethod.GET)
    @ApiOperation(value = "获取导航栏")
    public Result<List<TbPanelContent>> getNavList() {

        List<TbPanelContent> list = contentService.getNavList();
        return new ResultUtil<List<TbPanelContent>>().setData(list);
    }

    @RequestMapping(value = "/goods/home", method = RequestMethod.GET)
    @ApiOperation(value = "首页内容展示")
    public Result<List<TbPanel>> getProductHome() {

        List<TbPanel> list = contentService.getHome();
        return new ResultUtil<List<TbPanel>>().setData(list);
    }

    @RequestMapping(value = "/goods/productDet", method = RequestMethod.GET)
    @ApiOperation(value = "商品详情")
    public Result<Map<String, Object>> getProductDet(Long productId) {
        Map<String, Object> result = new HashMap<>();
        ItemDto item = itemService.getItemById(productId);
        if (item == null) {
            throw new XmallException("商品不存在");
        }
        TbItemSkuGoodCat cat = itemSkuGoodCatService.findTreeByItemId(productId);
        if (cat == null) {
            result.put("sku", null);
            result.put("items", new ArrayList<ItemDto>() {{
                this.add(item);
            }});
            return new ResultUtil<Map<String, Object>>().setData(result);
        }

        List<ItemDto> items = itemSkuGoodCatService.findBrotherItem(productId);
        List<SkuDto> list = levelOrder(cat);

        for (ItemDto itemDto : items) {
            List<String> skuLink = new ArrayList<>();
            TbItemSkuGoodCatAttr attr = itemSkuGoodCatAttrService.findByItemId(itemDto.getId());
            TbItemSkuGoodCat ccat = itemSkuGoodCatService.findById(attr.getItemSkuGoodCatId());
            skuLink.add(0, attr.getName());
            skuLink.add(0, ccat.getName());
            while (ccat.getFatherItemSkuGoodCatId() != null) {
                attr = itemSkuGoodCatAttrService.findById(ccat.getFatherItemSkuGoodCatId());
                ccat = itemSkuGoodCatService.findById(attr.getItemSkuGoodCatId());
                skuLink.add(0, attr.getName());
                skuLink.add(0, ccat.getName());
            }
            List<SkuDto> sku = new ArrayList<>();
            for (int i = 0; i < skuLink.size(); i += 2) {
//                List<SkuDto> attrSkuDtos = list.get(i / 2);
                for (SkuDto skuDto : list) {
                    if (skuDto.getName().equals(skuLink.get(i))) {
                        for (SkuDto s : skuDto.getSubs()) {
                            if (s.getName().equals(skuLink.get(i + 1))) {
                                sku.add(s);
                            }
                        }
                    }
                }
            }
            itemDto.setSkuDtos(sku);
            //获取折扣信息
            List<TbPreferential> preferentials = new ArrayList<>();
            List<TbPreferentialItem> preferentialItems = preferentialItemService.findByItemId(itemDto.getId(),TbPreferentialItem.STATUS_ABLE);
            if (preferentialItems != null && preferentialItems.size() > 0) {
                for (TbPreferentialItem preferentialItem : preferentialItems) {
                    if (preferentialItem != null) {
                        TbPreferential preferential = preferentialService.findById(preferentialItem.getPreferentialId());
                        if (preferential != null) {
                            preferentials.add(preferential);
                        }
                    }
                }
            }
            itemDto.setPreferentials(preferentials);
        }

        result.put("sku", list);
        result.put("items", items);
        return new ResultUtil<Map<String, Object>>().setData(result);
    }

    public List<SkuDto> levelOrder(TbItemSkuGoodCat root) {
        long id = 0;
        List<SkuDto> result = new ArrayList<>();
        if (root == null) return result;
        LinkedList<TbItemSkuGoodCat> queue = new LinkedList<>();
        // 1：根结点进入队列
        queue.offer(root);
        TbItemSkuGoodCat tmpNode = null;
        // 2：若队列非空，循环执行
        while (!queue.isEmpty()) {
//            List<SkuDto> tmpList = new ArrayList<>();
            //3. 获取当前层的节点数.
            int size = queue.size();
            // 4. 遍历当前层的节点
            for (int i = 0; i < size; i++) {
                // 5. 队首出队并将value加入子list
                tmpNode = queue.poll();
                SkuDto skuDto = new SkuDto();
                skuDto.setId(id++);
                skuDto.setName(tmpNode.getName());
                List<SkuDto> subs = new ArrayList<>();
                // 6. 将非空子树加入queue
                for (TbItemSkuGoodCatAttr attr : tmpNode.getAttrs()) {
                    SkuDto sub = new SkuDto();
                    sub.setId(id++);
                    sub.setName(attr.getName());
                    subs.add(sub);
                    TbItemSkuGoodCat node = attr.getNextCat();
                    if (node != null) {
                        queue.offer(node);
                    }
                }
                skuDto.setSubs(subs);
                result.add(skuDto);
            }
        }
        if (result.size() > 1) {
            Map<String, SkuDto> map = new HashMap<>();
            for (SkuDto skuDto : result) {
                List<SkuDto> subs = skuDto.getSubs();
                Map<String, SkuDto> subMap = new HashMap<>();
                for (SkuDto sub : subs) {
                    subMap.put(sub.getName(), sub);
                }
                if (map.get(skuDto.getName()) == null) {
                    map.put(skuDto.getName(), skuDto);
                }
                SkuDto get = map.get(skuDto.getName());
                subs = get.getSubs();
                for (SkuDto sub : subs) {
                    subMap.put(sub.getName(), sub);
                }
                skuDto.setSubs(new ArrayList<>(subMap.values()));
                map.put(skuDto.getName(), skuDto);
            }
            result.clear();
            for (SkuDto skuDto : map.values()) {
                result.add(skuDto);
            }
        }
        return result;
    }

    @RequestMapping(value = "/goods/allGoods", method = RequestMethod.GET)
    @ApiOperation(value = "所有商品")
    public Result<Page<Product>> getAllProduct(@RequestParam(defaultValue = "0") int page,
                                               @RequestParam(defaultValue = "10") int size,
                                               String sort,
                                               Long cid,
                                               @RequestParam(defaultValue = "-1") int priceGt,
                                               @RequestParam(defaultValue = "-1") int priceLte,
                                               @RequestParam(defaultValue = "-1") int originalGt,
                                               @RequestParam(defaultValue = "-1") int originalLte) {
        page += 1;
//        Page<Product> allGoodsResult = new Page<>(new PageParam(page, size));

//        String redisKey="allGoods:"+page+"_"+size+"_"+sort+"_"+cid+"_"+priceGt+"_"+priceLte;
//        //读取缓存
//        String temp=jedisClient.get(redisKey);
//        if(StringUtils.isNotBlank(temp)) {
//            allGoodsResult = new Gson().fromJson(temp, AllGoodsResult.class);
//            log.info("读取了" + redisKey + "缓存");
//            return new ResultUtil<AllGoodsResult>().setData(allGoodsResult);
//        }

        Page<Product> allGoodsResult = contentService.getAllProduct(page, size, sort, cid, priceGt, priceLte, originalGt, originalLte);

        //更新缓存
//        String value=new Gson().toJson(allGoodsResult);
//        jedisClient.set(redisKey,value);
//        jedisClient.expire(redisKey,604800);
//        log.info("更新了"+redisKey+"缓存");
        return new ResultUtil<Page<Product>>().setData(allGoodsResult);
    }

    @RequestMapping(value = "/goods/search", method = RequestMethod.GET)
    @ApiOperation(value = "搜索商品ES")
    public Result<Page<SearchItem>> searchProduct(@RequestParam(defaultValue = "") String key,
                                                  @RequestParam(defaultValue = "0") int page,
                                                  @RequestParam(defaultValue = "10") int size,
                                                  String sort,
                                                  @RequestParam(defaultValue = "-1") int priceGt,
                                                  @RequestParam(defaultValue = "-1") int priceLte) {
        if (sort == null) {
            sort = "";
        }
        page += 1;

        Page<SearchItem> searchResult = searchService.search(key, page, size, sort, priceGt, priceLte);

        //更新缓存
//        String value=new Gson().toJson(searchResult);
//        jedisClient.set(redisKey,value);
//        jedisClient.expire(redisKey,604800);
//        log.info("更新了"+redisKey+"缓存");
        return new ResultUtil<Page<SearchItem>>().setData(searchResult);
    }

    @RequestMapping(value = "/goods/recommend", method = RequestMethod.GET)
    @ApiOperation(value = "商品推荐板块")
    public Result<List<TbPanel>> getRecommendGoods() {

        List<TbPanel> list = contentService.getRecommendGoods();
        return new ResultUtil<List<TbPanel>>().setData(list);
    }

    @RequestMapping(value = "/goods/collect", method = RequestMethod.POST)
    @ApiOperation(value = "收藏/取消商品")
    public Result<String> collect(String token, Long itemId) {
        Member member = loginService.getUserByToken(token);
        if (member == null) {
            throw new NeedLoginException();
        }
        ItemDto itemDto = itemService.getItemById(itemId);
        if (itemDto == null) {
            throw new XmallException("商品不存在");
        }
        TbCollection tbCollection = collectionService.findByItemAndMember(itemId, member.getId());
        if (tbCollection == null) {
            tbCollection = new TbCollection();
            tbCollection.setItemId(itemId);
            tbCollection.setMemberId(member.getId());
            collectionService.save(tbCollection);
            return new ResultUtil<String>().setData("收藏成功");
        } else {
            collectionService.delete(tbCollection);
            return new ResultUtil<String>().setData("取消收藏成功");
        }
    }

    @RequestMapping(value = "/goods/collect", method = RequestMethod.GET)
    @ApiOperation(value = "获取是否收藏")
    public Result<Boolean> isCollected(String token, Long itemId) throws Exception {
        Member member = loginService.getUserByToken(token);
        if (member == null) {
            throw new NeedLoginException();
        }
        TbCollection collection = collectionService.findByItemAndMember(itemId, member.getId());
        return new ResultUtil<Boolean>().setData((collection == null) ? false : true);
    }

    @RequestMapping(value = "/goods/getCollectList", method = RequestMethod.GET)
    @ApiOperation(value = "获取收藏列表")
    public Result<Page<TbCollection>> getCollectList(String token, @RequestParam(defaultValue = "0") int pageNo, @RequestParam(defaultValue = "10") int pageSize) throws Exception {
        Member member = loginService.getUserByToken(token);
        if (member == null) {
            throw new NeedLoginException();
        }
        Page<TbCollection> page = collectionService.findPageByCriteria(new HashMap<String, Object>() {{
            if (member != null) {
                this.put("memberId", member.getId());
            }
        }}, new PageParam(pageNo, pageSize));
        for (TbCollection collection : page.getResult()) {
            ItemDto itemDto = itemService.getItemById(collection.getItemId());
            if (itemDto != null) {
                String[] imgs = (itemDto.getImage() == null ? "" : itemDto.getImage()).split(",");
                if (imgs.length > 0) {
                    collection.setGoodImg(imgs[0]);
                } else {
                    collection.setGoodImg("");
                }
                collection.setGoodName(itemDto.getTitle());
                collection.setPrice(itemDto.getPrice().doubleValue());
            }
        }
        return new ResultUtil<Page<TbCollection>>().setData(page);
    }

    @RequestMapping(value = "/goods/quickSearch", produces = "text/plain;charset=UTF-8", method = RequestMethod.GET)
    @ApiOperation(value = "快速搜索")
    public String getQuickSearch(@RequestParam(defaultValue = "") String key) {

        String result = null;
        try {
            result = HttpUtil.sendGet("http://" + ES_CONNECT_IP + ":" + ES_NODE_CLIENT_HTTP_PORT + "/item/itemList/_search?q=productName:" + key);
        } catch (Exception e) {
            log.error(e.toString());
        }
        return result;
    }

}
